#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define LEFT "["
#define RIGHT "]"
#define LABLE "#"
#define DELIM " \t"
#define LINE_SIZE 1024
#define ARGC_SIZE 32
#define EXIT_CODE 44

int quit = 0;
int last_node = 0;
extern char **environ;
char commandline[LINE_SIZE];
char *argv[ARGC_SIZE];

const char *getusername()
{
    return getenv("USER");
}

const char *gethostname()
{
    return getenv("HOSTNAME");
}

const char *getpwd()
{
    return getenv("PWD");
}

void Interact(char *cline, int size)
{
    printf(LEFT "%s@%s %s" RIGHT "" LABLE " ", getusername(), gethostname(), getpwd());
    char *s = fgets(cline, size, stdin);
    assert(s);
    (void)s;
    cline[strlen(cline) - 1] = '\0';
}

int stringsplit(char *cline, char *_argv[])
{
    int i = 0;
    _argv[i++] = strtok(cline, DELIM);
    while (_argv[i++] = strtok(NULL, DELIM))
        ;
    return i - 1;
}

void NormalExcute(char *_argv[])
{
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return;
    }
    else if (id == 0)
    {
        // child
        execvpe(_argv[0], _argv, environ);
        exit(EXIT_CODE); // 进程替换失败
    }
    else
    {
        int status = 0;
        int ret = waitpid(id, &status, 0);
        if (ret == id)
        {
            last_node = WEXITSTATUS(status);
        }
    }
}

int main()
{
    while (!quit)
    {
        Interact(commandline, sizeof(commandline));

        int argc = stringsplit(commandline, argv);
        if (argc == 0)
            continue;

        // 测试是否正确接受指令和选项
        // for(int i = 0; i < argc; ++i) printf("argv[%d]: %s\n", i, argv[i]);

        NormalExcute(argv);
    }

    return 0;
}
